#pragma once
#include "game_graphics.h"
#include "debug_constants.h"
#include "ttf.h"
//remove this, add new adapter class


using namespace std;

//TODO: Put this into a struct
SDL_Window * _window;
SDL_Window * _debug_window;
SDL_Renderer * _renderer;
SDL_Renderer * _debug_renderer;
SDL_Texture * _graphics_texture[TEXTURE_COUNT];
stack<SDL_Rect> _to_render;
stack<SDL_Color> _to_render_col;
stack<SDL_Rect> _to_render_screen_pos;
stack<SDL_Color> _to_render_col_screen_pos;


//GAME_GRAPHICS
SDL_Texture * graphics_load_texture(const char * path)
{
	SDL_Surface * s = SDL_LoadBMP(path);
	if (DEBUG_MODE){assert(s);}
	SDL_Texture * Result = SDL_CreateTextureFromSurface(_renderer, s);
	SDL_FreeSurface(s);
	return Result;
}

void graphics_unload()
{
	for(int i = 0; i < TEXTURE_COUNT; i++)
	{
		SDL_DestroyTexture(_graphics_texture[i]);
		_graphics_texture[i] = 0;
	}
}

int graphics_load()
{
	int i = 0;
	_graphics_texture[i++] = graphics_load_texture("texture_01.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_02.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_03.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_04.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_05.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_06.bmp");
	_graphics_texture[i++] = graphics_load_texture("texture_07.bmp");
	if (DEBUG_MODE){assert(i < TEXTURE_COUNT);}
	return 1;
}


V2i graphics_get_top_left_renderwindow()
{
	return G::GRAPHICS_RENDERWINDOW_TOP_LEFT;
}

void graphics_render_copy_on_screen(SDL_Renderer * renderer, SDL_Texture* text, V2 texture_top_left_screen_space, V2i texture_size)
{
	V2i top_left = graphics_get_top_left_renderwindow();

	SDL_Rect texture_rect = 
	{top_left.x + (int)texture_top_left_screen_space.x,
	top_left.y + (int)texture_top_left_screen_space.y,
	texture_size.x, texture_size.y};

	SDL_RenderCopy(renderer,text,NULL,&texture_rect);
}

void graphics_render_rect_outline_on_screen(SDL_Renderer * renderer, SDL_Color col, V2 top_left_screen_space, V2i size)
{
	SDL_Color c = {};
	SDL_GetRenderDrawColor(renderer,&c.r,&c.g,&c.b,&c.a);

	SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b,col.a);
	V2i top_left = graphics_get_top_left_renderwindow();
	SDL_Rect rect = {
		top_left.x + (int)top_left_screen_space.x,
		top_left.y + (int)top_left_screen_space.y,
		size.x, size.y};
	
	SDL_RenderDrawRect(renderer,&rect);

	SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b,c.a);
}

void graphics_render_rect_outline_on_screen(SDL_Color col, V2 top_left_screen_space, V2i size)
{
	SDL_Color c = {};
	SDL_GetRenderDrawColor(_renderer,&c.r,&c.g,&c.b,&c.a);

	SDL_SetRenderDrawColor(_renderer, col.r, col.g, col.b,col.a);
	V2i top_left = graphics_get_top_left_renderwindow();
	SDL_Rect rect = {
		top_left.x + (int)top_left_screen_space.x,
		top_left.y + (int)top_left_screen_space.y,
		size.x, size.y};
	
	SDL_RenderDrawRect(_renderer,&rect);

	SDL_SetRenderDrawColor(_renderer, c.r, c.g, c.b,c.a);
}

void graphics_render_rect_on_screen(SDL_Renderer * renderer, SDL_Color col, V2 top_left_screen_space, V2i size)
{
	SDL_Color c = {};
	SDL_GetRenderDrawColor(renderer,&c.r,&c.g,&c.b,&c.a);

	SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b,col.a);
	V2i top_left = graphics_get_top_left_renderwindow();
	SDL_Rect rect = {
		top_left.x + (int)top_left_screen_space.x,
		top_left.y + (int)top_left_screen_space.y,
		size.x, size.y};
	
	SDL_RenderFillRect(renderer,&rect);

	SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b,c.a);
}

//renders the screen position of the entitys absolute world position
static void graphics_render_entity(V2i entitySize,V2i camera_position, V2 world_position ,int spriteID, int highlight_amount)
	//(V2 entitySize, V2 entityRelPos,int spriteID, V2 cameraPos, V2i chunkID, int highlight_amount)
{
	V2 abs_entity_pos = world_position; //chunkID * G::GRAPHICS_TILE_SIZE*G::TILES_IN_CHUNK + entityRelPos;

	//render player
	V2 screen_player_pos = 
	{abs_entity_pos.x - camera_position.x, 
	abs_entity_pos.y - camera_position.y};

	graphics_render_copy_on_screen(_renderer,_graphics_texture[spriteID], screen_player_pos,entitySize);

	if( highlight_amount > 255){highlight_amount = 255;}
	graphics_add_rect_to_stack(abs_entity_pos,entitySize,(317*highlight_amount)%255,255-(917*highlight_amount)%255,(715*highlight_amount)%255,64);
}


void graphics_render_entity_imediate(V2i entitySize,V2i camera_position, V2 world_position ,int spriteID, int highlight_amount)
{
	graphics_render_entity(entitySize,camera_position, world_position, spriteID, highlight_amount);
	SDL_RenderPresent(_renderer);
}

void graphics_add_screen_rect_to_stack(V2i pos, V2i size, Uint8 r, Uint8 g, Uint8 b, Uint8 a )
{
	SDL_Rect Result = {pos.x, pos.y, size.x, size.y};
	SDL_Color col = {r,g,b,a/2};

	_to_render_col_screen_pos.push(col);
	_to_render_screen_pos.push(Result);
}

void graphics_add_rect_to_stack(V2i pos, V2i size, Uint8 r, Uint8 g, Uint8 b, Uint8 a )
{
	SDL_Rect Result = {pos.x, pos.y, size.x, size.y};
	SDL_Color col = {r,g,b,a/2};

	_to_render_col.push(col);
	_to_render.push(Result);
}

void graphics_render_stack( V2 cam_pos)
{
	while(_to_render.size() != 0)
	{
		SDL_Rect * r = &_to_render.top();	

		SDL_Color nc = _to_render_col.top();	_to_render_col.pop();
		graphics_render_rect_on_screen(_renderer, nc, v2(r->x-cam_pos.x, r->y-cam_pos.y),v2i(r->w,r->h)); 
		_to_render.pop();
	}
	while(_to_render_screen_pos.size()!=0)
	{
		SDL_Rect * r = &_to_render_screen_pos.top();	
		SDL_Color nc = _to_render_col_screen_pos.top();	_to_render_col_screen_pos.pop();
		graphics_render_rect_on_screen(_renderer, nc, v2(r->x, r->y),v2i(r->w,r->h)); 
		_to_render_screen_pos.pop();
	}
}


void graphics_destroy(GraphicsWindow window)
{
	//textures
	if (window == WINDOW_GAME)
	{
		graphics_unload();
		SDL_DestroyRenderer(_renderer);
		_renderer = 0;
		SDL_DestroyWindow(_window);
		_window = 0;
	}
	if (window == WINDOW_DEBUG)
	{
		SDL_DestroyRenderer(_debug_renderer);
		_debug_renderer = 0;
		SDL_DestroyWindow(_debug_window);
		_debug_window = 0;
	}
}



/*
void graphics_render_text(string msg, SDL_Renderer * r)
{
	SDL_Color col = {128,128,128,128};
	SDL_Rect dest = {0,0,100,30};
	graphics_render_copy_on_screen(r,  ttf_render(r, msg.c_str() ,col,32),
		v2(dest.x,dest.y),v2i(dest.w,dest.h));

	//SDL_RenderCopy(r, ttf_render(r, msg.c_str() ,col,32),NULL,&dest);
}
*/
/*
SDL_SetRenderDrawColor(debug_renderer, 255,255,255,255);
	SDL_RenderClear(debug_renderer);
	for (int i = 0; i < sizeof(debug_text) / sizeof(debug_text[0]);i++)
	{
		graphics_render_text(debug_text[i],debug_renderer);
	}
	SDL_RenderPresent(debug_renderer);
*/

SDL_Texture * graphics_get_string_texture(SDL_Color c, std::string msg, GraphicsWindow window, int font_size)
{
	SDL_Texture * result = 0;
	SDL_Renderer * renderer = 0;
	if (window == WINDOW_DEBUG){renderer = _debug_renderer;}
	if (window == WINDOW_GAME){renderer = _renderer;}

	result = ttf_render(renderer, msg.c_str() ,c,font_size);
	return result;
}

void graphics_draw_string(SDL_Texture * string_texture, Rect bounds, GraphicsWindow window )
{
	SDL_Renderer * renderer = 0;
	if (window == WINDOW_DEBUG){renderer = _debug_renderer;}
	if (window == WINDOW_GAME){renderer = _renderer;}
	
	SDL_Rect dest = {bounds.min.x,
					bounds.min.y,
					bounds.max.x - bounds.min.x,
					bounds.max.y - bounds.min.y};
	
	SDL_RenderCopy(renderer,string_texture,NULL,&dest);
}

//pull ttf out into main
void graphics_init(GraphicsWindow window)
{
	if (window == WINDOW_GAME)
	{
		_window = SDL_CreateWindow("SDL WINDOW",
			SDL_WINDOWPOS_UNDEFINED,
			SDL_WINDOWPOS_UNDEFINED,
			G::SCREEN_WIDTH+2*G::SCREEN_DEBUG_EXTRA_PIXELS,
			G::SCREEN_HEIGHT+2*G::SCREEN_DEBUG_EXTRA_PIXELS,
			SDL_WINDOW_OPENGL);
		if (DEBUG_MODE){assert(_window);}
		_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED );//| SDL_RENDERER_PRESENTVSYNC);
		SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255 );
		SDL_SetRenderDrawBlendMode(_renderer,SDL_BLENDMODE_BLEND);
		graphics_load();
	}

	if (window == WINDOW_DEBUG)
	{
		_debug_window = SDL_CreateWindow("Debug Window",8,32,512,256,SDL_WINDOW_OPENGL);
		_debug_renderer = SDL_CreateRenderer(_debug_window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
		SDL_SetRenderDrawColor(_debug_renderer,255,0,0,255);
	}
}

void graphics_start_render(GraphicsWindow window)
{
	SDL_Renderer * target_renderer = 0; 
	if(window == GraphicsWindow::WINDOW_GAME){target_renderer = _renderer;}
	else if (window == GraphicsWindow::WINDOW_DEBUG){target_renderer = _debug_renderer;}
	SDL_SetRenderDrawColor(target_renderer, 255,255,255,255);
	SDL_RenderClear(target_renderer);

}
void graphics_final_render(GraphicsWindow window)
{
	SDL_Renderer * target_renderer = 0; 
	if(window == GraphicsWindow::WINDOW_GAME){target_renderer = _renderer;}
	else if (window == GraphicsWindow::WINDOW_DEBUG){target_renderer = _debug_renderer;}
	SDL_RenderPresent(target_renderer);
}



